﻿using Little.Soldier.SWIFT;
using Little.Soldier.SWIFT.Validation;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Little.Soldier
{
  internal class U007F
  {
    private StringBuilder _StringBuilder;
    private SwiftMessage _SwiftMessage;
    private TextReader _TextReader;

    internal SwiftMessage Message
    {
      get
      {
        return this._SwiftMessage;
      }
    }

    internal virtual string Data
    {
      set
      {
        this.Reader = (TextReader) new StringReader(value);
      }
    }

    internal virtual TextReader Reader
    {
      set
      {
        this._StringBuilder = new StringBuilder();
        this._TextReader = value;
      }
    }

    internal U007F()
    {
    }

    internal U007F(Stream stream)
      : this((TextReader) new StreamReader(stream))
    {
    }

    internal U007F(TextReader reader)
    {
      this.Reader = reader;
    }

    internal U007F(string message)
      : this((TextReader) new StringReader(message))
    {
    }

    internal virtual SwiftBlock4 GetSwiftBlock4(SwiftBlock4 block, string text)
    {
      text = this.U0092U0003(text);
      int index1 = 0;
      if ((int) text[index1] == 52)
        ++index1;
      if ((int) text[index1] == 58)
        ++index1;
      while (index1 < text.Length)
      {
        int startIndex1 = index1;
        char ch;
        do
        {
          int index2;
          index1 = (index2 = index1) + 1;
          ch = text[index2];
        }
        while (index1 < text.Length && (int) ch != 58 && ((int) ch != 123 && (int) ch != 125));
        int num1 = 0;
        if ((int) ch == 125 && (int) text[index1 - 1] == 45)
          num1 = 1;
        string text1 = text.Substring(startIndex1, index1 - startIndex1 - num1 - 1).Trim();
        if ("" != text1)
          block.U0084(text1);
        if (index1 != text.Length)
        {
          int startIndex2 = 0;
          string buffer = (string) null;
          string unparsedText = (string) null;
          switch (ch)
          {
            case ':':
              startIndex2 = this.U0001U0004(text, index1);
              buffer = text.Substring(index1, startIndex2 - index1);
              break;
            case '{':
              if (text.Substring(index1).StartsWith("1:"))
              {
                int startIndex3 = index1 <= 0 ? 0 : index1 - 1;
                startIndex2 = startIndex3 + 1;
                string str = text.Substring(startIndex2);
                while (startIndex2 < text.Length && !str.StartsWith("{1:"))
                  startIndex2 = this.U0093U0003(text, startIndex2 + 1);
                string text2 = text.Substring(startIndex3, startIndex2 - startIndex3);
                block.U0084(text2);
                break;
              }
              else
              {
                startIndex2 = this.U0093U0003(text, index1);
                buffer = text.Substring(index1, startIndex2 - 1 - index1);
                int num2 = buffer.IndexOf("{1:");
                if (num2 != -1)
                {
                  unparsedText = buffer.Substring(num2);
                  buffer = buffer.Substring(0, num2);
                  break;
                }
                else
                  break;
              }
            case '}':
              if (index1 != text.Length)
              {
                int length = text.Length;
                break;
              }
              else
                break;
          }
          if (buffer != null)
          {
              SwiftTag swiftTag = this.GetSwiftTag(buffer, unparsedText);
            if (swiftTag != null)
              block.AddTag(swiftTag);
          }
          index1 = startIndex2;
        }
      }
      return block;
    }

    internal string U0092U0003(string data)
    {
      switch (data)
      {
        case null:
          return data;
        default:
          if (data.Length != 0)
          {
            int length1 = data.Length;
            int length2;
            if ((int) data[length2 = length1 - 1] == 45)
            {
              if (length2 > 0 && (int) data[length2 += -1] == 10 && (length2 > 0 && (int) data[length2 += -1] != 13))
                ++length2;
              data = length2 <= 0 ? "" : data.Substring(0, length2);
              goto case null;
            }
            else
              goto case null;
          }
          else
            goto case null;
      }
    }

    internal int U0093U0003(string s, int start)
    {
      int num = 0;
      char ch;
      do
      {
        int index;
        start = (index = start) + 1;
        switch (ch = s[index])
        {
          case '{':
            ++num;
            break;
          case '}':
            num += -1;
            break;
        }
      }
      while (start < s.Length && (num >= 0 || num == 0 && (int) ch != 125));
      return start;
    }

    internal virtual SwiftBlockBase GetSwiftBlockBase(List<ValidationError> parseError)
    {
      this.U0096U0003();
      string str = this.U009EU0003();
      if (str == "")
        return (SwiftBlockBase) null;
      if (str.StartsWith("1:") && this._SwiftMessage != null && this._SwiftMessage.Block1 != null)
      {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append("{");
        stringBuilder.Append(str);
        stringBuilder.Append("}");
        bool flag = false;
        while (!flag)
        {
          char[] buffer = new char[128];
          if (this._TextReader.Read(buffer, 0, 128) > 0)
            stringBuilder.Append(buffer);
          else
            flag = true;
        }
        UnparsedTextList unparsedTextList = this.GetUnparsedTextList(((object)stringBuilder).ToString());
        if (unparsedTextList != null)
          this._SwiftMessage.UnparsedTexts = unparsedTextList;
        return (SwiftBlockBase) null;
      }
      else
      {
        char ch = this.U0098U0003(str);
        switch (ch)
        {
          case ' ':
            if (parseError != null)
            {
              ValidationError validationError = new ValidationError(ValidationErrorType.UsupportedBlockFormat, ((object) new StringBuilder().Append("The block '").Append(str).Append("' could not be identified")).ToString());
              parseError.Add(validationError);
            }
            return (SwiftBlockBase) null;
          case '1':
            SwiftBlock1 swiftBlock1 = new SwiftBlock1(this._SwiftMessage);
            swiftBlock1.SetValue(str, parseError);
            return (SwiftBlockBase) swiftBlock1;
          case '2':
            if (this.IsInput(str))
            {
              SwiftBlock2Input swiftBlock2Input = new SwiftBlock2Input(this._SwiftMessage);
              swiftBlock2Input.SetValue(str, parseError);
              return (SwiftBlockBase) swiftBlock2Input;
            }
            else
            {
              SwiftBlock2Output swiftBlock2Output = new SwiftBlock2Output(this._SwiftMessage);
              swiftBlock2Output.SetValue(str, parseError);
              return (SwiftBlockBase) swiftBlock2Output;
            }
          case '3':
            return (SwiftBlockBase)this.GetSwiftTagListBlock((SwiftTagListBlock) new SwiftBlock3(this._SwiftMessage), str);
          case '4':
            return (SwiftBlockBase)this.GetSwiftBlock4(new SwiftBlock4(this._SwiftMessage), str);
          case '5':
            return (SwiftBlockBase)this.GetSwiftTagListBlock((SwiftTagListBlock) new SwiftBlock5(this._SwiftMessage), str);
          default:
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(ch);
            return (SwiftBlockBase) this.GetSwiftTagListBlock((SwiftTagListBlock) new SwiftBlockUser(this._SwiftMessage, ((object) stringBuilder).ToString()), str);
        }
      }
    }

    internal virtual SwiftTag GetSwiftTag(string buffer, string unparsedText)
    {
      int length1 = buffer.IndexOf(':');
      string str1 = (string) null;
      string str2;
      if (length1 != -1)
      {
        str1 = buffer.Substring(0, length1);
        str2 = buffer.Substring(length1 + 1);
      }
      else
        str2 = buffer;
      if ((str1 == null || str1 == "") && (str2 == null || str2 == ""))
        return (SwiftTag) null;
      int length2 = str2.Length;
      if (length2 > 0)
      {
        switch (str2[length2 - 1])
        {
          case '\n':
          case '\r':
            length2 += -1;
            break;
        }
      }
      if (length2 > 0)
      {
        switch (str2[length2 - 1])
        {
          case '\n':
          case '\r':
            length2 += -1;
            break;
        }
      }
      if (length2 != str2.Length)
        str2 = str2.Substring(0, length2);
      SwiftTag swiftTag = new SwiftTag();
      swiftTag.Name = str1;
      swiftTag.Value = str2;
      if (unparsedText != null)
          swiftTag.UnparsedTexts = this.GetUnparsedTextList(unparsedText);
      return swiftTag;
    }

    internal virtual void U0096U0003()
    {
      int num;
      do
      {
        num = this.GetMaxLength();
      }
      while (num != -1 && !this.U009AU0003((char) num));
    }

    internal int GetMaxLength()
    {
      int num = this._TextReader.Read();
      if (num >= 0)
        this._StringBuilder.Append((char) num);
      return num;
    }

    internal virtual char U0098U0003(string s)
    {
        switch (s)
        {
            case null:
                return ' ';
            default:
                if (s.Length > 1)
                {
                    char ch = s[0];
                    if (48 <= (int) ch && (int) ch <= 57 || 97 <= (int) ch && (int) ch <= 122 || 65 <= (int) ch && (int) ch <= 90)
                        return ch;
                    else
                        goto case null;
                }
                else
                    goto case null;
        }
    }

    internal bool U0099U0003(char c)
    {
      return (int) c == 125;
    }

    internal bool U009AU0003(char c)
    {
      return (int) c == 123;
    }

    internal bool IsInput(string s)
    {
      int num = s.IndexOf(':');
      if (num >= 0 && num + 1 < s.Length)
        return s[num + 1].ToString().ToUpper() == "I";
      else
        return false;
    }

    internal SwiftMessage GetSwiftMessage(List<ValidationError> parseError)
    {
      SwiftMessage swiftMessage = new SwiftMessage(false);
      this._SwiftMessage = swiftMessage;
      try
      {
        bool flag = false;
        do
        {
            SwiftBlockBase swiftBlock = this.GetSwiftBlockBase(parseError);
          if (swiftBlock != null)
            this._SwiftMessage.AddBlock(swiftBlock);
          else
            flag = true;
        }
        while (!flag);
      }
      finally
      {
        this._SwiftMessage = (SwiftMessage) null;
      }
      return swiftMessage;
    }

    //(J)
    int startIndex2;
    private UnparsedTextList GetUnparsedTextList(string unparsedText)
    {
        UnparsedTextList unparsedTextList = (UnparsedTextList) null;
        for (int startIndex1 = 0; startIndex1 < unparsedText.Length;)
        {
            startIndex1 = startIndex2;
            startIndex2 = startIndex1 + 1;
            string str = unparsedText.Substring(startIndex2);
label_4:
            while (startIndex2 + 1 < unparsedText.Length && !str.StartsWith("{1:"))
            {
                startIndex2 = this.U0093U0003(unparsedText, startIndex2 + 1);
                while (true)
                {
                    if (startIndex2 < unparsedText.Length && char.IsWhiteSpace(unparsedText[startIndex2]))
                        ++startIndex2;
                    else
                        goto label_4;
                }
            }
            string text = unparsedText.Substring(startIndex1, startIndex2 - startIndex1).Trim();
            if (text != "")
            {
                if (unparsedTextList == null)
                unparsedTextList = new UnparsedTextList();
                unparsedTextList.U0080U0003(text);
            }
        }
        return unparsedTextList;
    }

    internal virtual string U009EU0003()
    {
      int length = this._StringBuilder.Length;
      int num1 = 0;
      int num2 = 1;
      bool flag = false;
      while (!flag)
      {
        int num3 = this.GetMaxLength();
        if (num3 == -1)
        {
          flag = true;
        }
        else
        {
          if (this.U009AU0003((char) num3))
            ++num2;
          if (this.U0099U0003((char) num3))
          {
            num2 += -1;
            if (num2 == 0)
              flag = true;
            else
              ++num1;
          }
          else
            ++num1;
        }
      }
      int num4 = length + num1;
      if (num2 != 0)
      {
        int num5 = num4 - length;
      }
      return this._StringBuilder.ToString(length, num4 - length);
    }

    internal virtual SwiftTagListBlock GetSwiftTagListBlock(SwiftTagListBlock b, string s)
    {
      int num1 = s.IndexOf(':');
      if (num1 >= 0 && num1 + 1 < s.Length)
      {
        string str = s.Substring(num1 + 1);
        for (int startIndex = 0; startIndex < str.Length; ++startIndex)
        {
          if ((int) str[startIndex] == 123)
          {
            int num2 = str.IndexOf('}', startIndex);
            if (num2 >= 0 && str.Length > num2)
            {
              string inner = str.Substring(startIndex + 1, num2 - startIndex - 1);
              startIndex = num2;
              SwiftTag swiftTag = new SwiftTag(inner);
              b.AddTag(swiftTag);
            }
          }
          else
          {
            int index = startIndex;
            while (index < str.Length && (int) str[index] != 123)
              ++index;
            string text = str.Substring(startIndex, index - startIndex).Trim();
            if (!"".Equals(text))
              b.U0084(text);
            startIndex = index - 1;
          }
        }
      }
      return b;
    }

    private int U0001U0004(string s, int start)
    {
      for (; start < s.Length; ++start)
      {
        char ch1 = s[start];
        if ((int) ch1 == 13 || (int) ch1 == 10)
        {
          int num = start;
          if (start + 1 == s.Length)
            return start;
          char ch2 = s[++start];
          switch (ch2)
          {
            case '\n':
            case '\r':
              if (start == s.Length)
                return start;
              ch2 = s[++start];
              break;
          }
          if ((int) ch2 == 123 || (int) ch2 == 125)
          {
            start = num;
            return start;
          }
          else
          {
            if ((int) ch2 == 58 && start != s.Length)
            {
              switch (s[++start])
              {
                case '\r':
                case '\n':
                  break;
                default:
                  start = num;
                  return start;
              }
            }
            start = num;
          }
        }
        else
        {
          if ((int) ch1 == 45)
          {
            ch1 = start + 1 >= s.Length ? ' ' : s[start + 1];
            if ((int) ch1 == 125)
              return start;
          }
          if ((int) ch1 == 125)
            return start;
        }
      }
      return start;
    }
  }
}
